<!-- WEB 仓库 》 弹窗 -->

<template>
  <el-dialog v-bind="config" :visible.sync="model">
    <!-- 标题插槽 -->
    <template #title>
      <slot name="title" :title="modalTitle" />
    </template>

    <!-- 页签插槽 -->
    <div v-if="hasTab" class="CoreWeb-Modal-tab">
      <slot name="tab" />
    </div>

    <!-- 默认插槽 -->
    <div class="CoreWeb-Modal-body" :class="fullScreen ? 'full' : null">
      <slot />
    </div>

    <!-- 底部插槽 -->
    <template v-if="!noFooter" #footer>
      <el-button v-show="!noCancel" class="CoreWeb-Modal-canel" v-bind="isShow ? closeBtn : cancelBtn" @click="toClose">
        {{ isShow ? btnMap.close : btnMap.cancel }}
      </el-button>

      <el-button v-if="firstConfirm && isShow && !noEdit" v-bind="confirmBtn" @click="toEdit">{{
        btnMap.edit
      }}</el-button>
      <el-button v-if="firstConfirm && !isShow" v-bind="confirmBtn" @click="toSubmit">{{ btnMap.confirm }}</el-button>

      <slot name="footer">
        <el-button v-if="isShow && !noEdit" v-bind="confirmBtn" @click="toEdit">{{ btnMap.edit }}</el-button>
        <el-button v-if="!isShow" v-bind="confirmBtn" @click="toSubmit">{{ btnMap.confirm }}</el-button>
      </slot>

      <el-button v-if="lastConfirm && isShow && !noEdit" v-bind="confirmBtn" @click="toEdit">{{
        btnMap.edit
      }}</el-button>
      <el-button v-if="lastConfirm && !isShow" v-bind="confirmBtn" @click="toSubmit">{{ btnMap.confirm }}</el-button>
    </template>
  </el-dialog>
</template>

<script>
// ============================== 导入依赖 ============================== //

import CORE from '@/CORE'
import { MessageBox } from 'element-ui'
import mixPath from '../mixPath'
import WebForm from '../WebForm'

const name = 'WebModal'

// ============================== 导出组件 ============================== //

export default {
  /**
   * 名称定义 (实际使用名称)
   */
  name,

  /**
   * 混入列表 (配置选项合并)
   */
  mixins: [mixPath],

  /**
   * 属性注册 (抽取以便查阅)
   */
  props: CORE.WEB[name],

  /**
   * 计算属性 (慎用箭头函数)
   */
  computed: {
    /**
     * 尺寸
     */
    size: WebForm.computed.size,

    /**
     * 是否有页签
     */
    hasTab() {
      if (!this.$scopedSlots) return false
      return this.$scopedSlots.tab
    },

    /**
     * 显示弹窗 (双向绑定)
     */
    model: {
      get() {
        const { visible, modal = '' } = this.state
        return visible && ['show', 'add', 'edit'].includes(modal)
      },
      set() {
        this.toClose()
      },
    },

    /**
     * 是否为查看弹窗
     */
    isShow() {
      return this.state.modal === 'show'
    },

    /**
     * 弹窗类型
     */
    modalType() {
      const { modal = '' } = this.state
      return CORE.keyPre(modal)
    },

    /**
     * 开始方法
     */
    start() {
      return `start${this.modalType}`
    },

    /**
     * 提示映射
     */
    tipMap() {
      const MAP = CORE.isJSON(this.state.MAP) ? this.state.MAP : {}
      const WORD = this.word || MAP.WORD
      const title = CORE.isString(this.title) ? this.title : ''
      const obj = CORE.isJSON(this.title) ? this.title : {}
      const get = (NAME) => CORE.isString(MAP[NAME]) ? MAP[NAME] : CORE.MAP[`TIP_${NAME}`]
      const getTip = (name) => {
        if (title) return title
        if (obj[name]) return obj[name]
        if (this[`${name}Title`]) return this[`${name}Title`]
        if (this[name]) return `${this[name]}${WORD}`
        if (this.word) return `${get(name.toUpperCase())}${this.word}`
        return MAP[`tip${CORE.keyPre(name)}`]
      }
      const getTipContent = (name) => {
        if (this[`${name}Tip`]) return this[`${name}Tip`]
        const pre = this.tipPrefix || get('PREFIX')
        const mid = this.tipMiddle || get('MIDDLE')
        const suf = this.tipSuffix || get('SUFFIX')
        return `${pre}${this[name] || get(name.toUpperCase())}${mid}${WORD || '数据'}${suf}`
      }

      return {
        tipSubmit: getTip('submit'),
        tipShow: getTip('show'),
        tipAdd: getTip('add'),
        tipEdit: getTip('edit'),
        tipDel: getTip('del'),
        tipPass: getTip('pass'),
        tipRej: getTip('rej'),
        tipSubmitContent: getTipContent('submit'),
        tipDelContent: getTipContent('del'),
        tipPassContent: getTipContent('pass'),
        tipRejContent: getTipContent('rej'),
      }
    },

    /**
     * 按钮映射
     */
    btnMap() {
      return {
        edit: this.edit || CORE.MAP.TIP_EDIT,
        confirm: this.confirm || CORE.MAP.TIP_CONFIRM,
        cancel: this.cancel || CORE.MAP.TIP_CANCEL,
        close: this.close || CORE.MAP.TIP_CLOSE,
      }
    },

    /**
     * 弹窗标题
     */
    modalTitle() {
      return this.tipMap[`tip${this.modalType}`] || ''
    },

    /**
     * 提示内容
     */
    tipContent() {
      return this.tipMap[`tip${this.modalType}Content`] || ''
    },

    /**
     * 弹窗配置
     */
    config() {
      const {
        width,
        fullWide,
        fullWidth,
        fullHigh,
        fullScreen,
        top,
        center,
        className,
        modalClass,
        size,
        large,
        huge,
      } = this

      const isShow = this.state.modal === 'show'
      const modalWidth = CORE.isInt(width) ? `${width}px` : width
      const fullModalWidth = CORE.isInt(fullWidth) ? `${fullWidth}px` : fullWidth
      const modalTop = CORE.isInt(top) ? `${top}px` : top
      const finalWidth = modalWidth || (fullWide ? fullModalWidth : null)
      const sizeStr = finalWidth || fullScreen ? 'width' : size || (huge ? 'huge' : large ? 'large' : 'default')
      const noFoClass = this.noFooter ? ` ${className}-noFooter` : ''
      const wideClass = fullWide ? ` ${className}-fullWide` : ''
      const highClass = fullHigh ? ` ${className}-fullHigh` : ''

      return {
        ...this.elProps,
        width: finalWidth,
        closeOnClickModal: isShow,
        title: this.modalTitle,
        top: modalTop,
        center,
        fullscreen: fullScreen,
        customClass: `${className} ${className}-${sizeStr}${noFoClass}${wideClass}${highClass} ${modalClass}`,
        appendToBody: true,
      }
    },

    /**
     * 确认配置
     */
    confirmConig() {
      const { tipConfirm, tipCancel, modal = '' } = this.state
      const type = this[`${modal}Type`] || ''
      return {
        ...CORE.CONFIRM.CONFIG[type.toUpperCase()],
        confirmButtonText: tipConfirm,
        cancelButtonText: tipCancel,
        type,
      }
    },
  },

  /**
   * 监听属性 (深度 deep 首次 immediate)
   */
  watch: {
    /**
     * 监听弹窗可见
     */
    'state.visible': {
      immediate: true,
      handler(visible) {
        const { modal = '' } = this.state
        if (visible && ['submit', 'del', 'pass', 'rej'].includes(modal)) this.showConfirm()
        visible && CORE.iframeNotice(true) // 如果当前是 iframe 中的页面，则通知父层升降该 iframe 的 z-index
      },
    },
  },

  /**
   * 销毁之前 (先抽取再调用)
   */
  beforeDestroy() {
    if (this.state.visible) this.toClose()
  },

  /**
   * 本地方法 (轻量重要在前)
   */
  methods: {
    /**
     * 确认弹窗
     */
    showConfirm() {
      const { tipContent, modalTitle, confirmConig, commit, start, toClose } = this
      MessageBox.confirm(tipContent, modalTitle, confirmConig)
        .then(() => commit(start))
        .catch(toClose)
    },

    /**
     * 关闭弹窗
     */
    toClose() {
      this.commit('closeModal')
      this.$emit('close')
      CORE.iframeNotice(false) // 如果当前是 iframe 中的页面，则通知父层升降该 iframe 的 z-index
    },

    /**
     * 点击修改
     */
    toEdit() {
      this.commit('openEdit')
    },

    /**
     * 提交表单 (重复提交时，可以闪烁提示)
     */
    async toSubmit() {
      const { onSubmit, commit, start, modalTitle } = this
      const { refForm, MAP } = this.state
      if (refForm) await refForm.check()
      MAP[start.replace('state', 'tip')] = modalTitle // 记录弹窗标题
      onSubmit ? onSubmit() : commit(start)
    },
  },
}
</script>
